import { isValidElement } from 'react';

import { Tag, UploadFile, UploadProps } from 'antd';
import dayjs, { ConfigType } from 'dayjs';
import Decimal from 'decimal.js-light';
import { Base64 } from 'js-base64';
import { isPlainObject } from 'lodash-es';

import { request } from './api';

export function replaceMultiText(text: string, replaceText: string): string {
  return text.replace(new RegExp(`(${replaceText}){1,}`, 'g'), '$1');
}

/**
 * 生成uuid
 */
export function genUUID(): string {
  const uuid: string[] = [];
  const hexDigits = '0123456789abcdef';

  for (let i = 0; i < 36; i++) {
    uuid[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }

  uuid[14] = '4';
  uuid[19] = hexDigits.substr(((uuid as any)[19] & 0x3) | 0x8, 1);
  uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';

  return `u${(uuid.join('') as any).replaceAll('-', '')}`;
}

/** 格式化值 */
export function formatValue<T = string | number | null | undefined>(
  /** 要渲染的值 */
  v?: T,
  /** 换行个数 */
  max?: number
): string | T {
  if (v === null || typeof v === 'undefined') {
    return emptyText;
  }

  if (typeof v === 'string' && !v) {
    return emptyText;
  }

  if (typeof v === 'number' && isNaN(v)) {
    return emptyText;
  }

  const s = String(v);

  if (max && s.length > max) {
    return s.replace(new RegExp(`(?![^\\n]{1,${max}}$)([^\\n]{1,${max}})\\s`, 'g'), '$1\n');
  }

  return v;
}

/** 格式化日期 */
export function formatDate(v: ConfigType, format = 'YYYY-MM-DD HH:mm:ss'): string {
  if (!v) {
    return emptyText;
  }

  const m = dayjs(v);

  if (!m.isValid()) {
    return emptyText;
  }

  return m.format(format);
}

/**
 * 格式化数值
 */
export const formatNumber = (
  v: string | number | null | undefined,
  /** 小数位数 */
  digit = 0,
  /** 回调 */
  cb?: (v: Decimal) => Decimal
): string => {
  if (v === null || typeof v === 'undefined') {
    return emptyText;
  }

  const isDecimal = /^(-?)(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;

  if (typeof v === 'string' && !isDecimal.test(v)) {
    return emptyText;
  }

  const p = new Decimal(v);

  return (cb ? cb(p) : p).toFixed(digit, Decimal.ROUND_DOWN);
};

export function formatEnum(text: unknown, valueEnum?: ValueEnumMap<string | number>) {
  if (valueEnum instanceof Map) {
    const map = valueEnum.get(Number(text)) || valueEnum.get(String(text));

    if (!map) {
      return formatValue(text);
    }

    if (isValidElement(map)) {
      return map;
    }

    if (isPlainObject(map)) {
      const valueEnumObj = map;

      return <Tag color={valueEnumObj.color}>{valueEnumObj.text}</Tag>;
    }

    return map;
  }

  return formatValue(text);
}

// 解析图片地址
export const parseSrc = (src?: undefined | null | string) => {
  if (typeof src !== 'string') {
    return undefined;
  }

  if (src.startsWith('http')) {
    return src;
  }

  // base64
  if (/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(src)) {
    if (src.startsWith('/')) {
      return `data:image/png;base64,${src}`;
    }

    if (src.startsWith(',/')) {
      return `data:image/png;base64${src}`;
    }

    return `data:image/png;base64,${src}`;
  }

  if (src.startsWith('/')) {
    return replaceMultiText(
      `${import.meta.env.VITE_PROXY_KEY}${src}?token=${request.defaults.headers.token}`,
      '/'
    );
  }

  return src;
};

/** 获取浏览器滚动条宽度 */
export function getBrowserScrollWidth(): number {
  // Add temporary box to wrapper
  const scrollbox = document.createElement('div');

  // Make box scrollable
  scrollbox.style.overflow = 'scroll';
  // Append box to document
  document.body.appendChild(scrollbox);

  // Measure inner width of box
  const scrollBarWidth = scrollbox.offsetWidth - scrollbox.clientWidth;

  // Remove box
  document.body.removeChild(scrollbox);

  return scrollBarWidth;
}

/**
 * 格式化文件大小
 */
export const formatFileSize = (size: number) => {
  const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

  let i = 0;
  while (size >= 1024) {
    size /= 1024;
    i++;
  }

  return `${size.toFixed(2)} ${units[i]}`;
};

/** 像素转rem, 用于echarts */
export const px = (value: number): number => {
  const clientWidth =
    window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

  return value * (clientWidth / 1920);
};

// px2rem
export const px2rem = (px: number): string => {
  // 设计稿尺寸
  const designWidth = 1920 / 10;

  return `${(px / designWidth).toFixed(6)}rem`;
};

/** 获取文件名 */
function getFileName(name: string): string {
  return name.split('/').pop() || name;
}

/** 获取图片预览地址 */
function getPrevUrl(url: string) {
  return parseSrc(url);
}

export const formatUploadFile = (fileList: UploadProps['fileList']): UploadFile[] => {
  if (!fileList) {
    return [];
  }

  if (Array.isArray(fileList)) {
    return fileList.map((file) => {
      if (typeof file === 'string') {
        return {
          uid: file,
          name: getFileName(file),
          url: getPrevUrl(file),
          status: 'done',
          response: {
            data: {
              fileUrl: file
            }
          }
        };
      }

      return file;
    });
  }

  return [];
};

//打开预览页面
export const openUrl = (url: string | undefined) => {
  const host =
    process.env.NODE_ENV === 'development'
      ? 'http://10.36.16.30:8012'
      : 'http://10.20.7.100:81/fileview';
  const port =
    process.env.NODE_ENV === 'development'
      ? 'http://10.36.16.129:3288/api'
      : 'http://10.20.7.100:81/api';
  const token = '1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw';
  window.open(
    host +
      '/onlinePreview?url=' +
      encodeURIComponent(Base64.encode(`${port}${url}?token=${localStorage.getItem('token')}`)) +
      '&token=' +
      token,
    '文件预览',
    `height=600,width=900,top=${screen.availHeight / 2 - 300},left=${
      screen.availWidth / 2 - 450
    },toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no`
  );
};

// 函数用于根据ID查找名称
export const findIdByName = (tree: any[], key: string): string | undefined => {
  // 遍历树的每个节点
  for (const node of tree) {
    // 如果找到匹配的名称，返回ID
    if (node.key === key) {
      return node.title;
    }
    // 如果节点有子节点，递归查找
    if (node.children) {
      const title = findIdByName(node.children, key);
      // 如果在子节点中找到，直接返回结果
      if (title !== undefined) {
        return title;
      }
    }
  }
  // 如果没有找到，返回undefined
  return undefined;
};

//获取文件名
export const getFileNameFromAttachmentHeader = (header: string): string => {
  // 如果字符串中包含多个filename=，取最后一个
  const filenamePart = header.split('filename=').pop() || '';

  // 解码URL编码的部分
  const decodedFilename = decodeURIComponent(filenamePart);

  // 移除可能存在的双引号
  const cleanedFilename = decodedFilename.replace(/"/g, '');

  // 提取文件名
  // eslint-disable-next-line no-control-regex
  const matches = cleanedFilename.match(/[^\x00-\x1F<>:"/\\|?*\x7F]+$/);
  if (matches) {
    return matches[0];
  }

  // 处理无效的情况，返回空字符串或者默认值
  return '';
};
